//
//  NSMutableString+ZXAvoidCrash.m
//  ZXAvoidCrash
//
//  Created by 朱新明 on 2023/3/29.
//

#import "NSMutableString+ZXAvoidCrash.h"
#import "ZXAvoidCrashRuntime.h"
#import "ZXAvoidCrashReport.h"

@implementation NSMutableString (ZXAvoidCrash)

+ (void)zx_avoidCrashExchangeMethod{
    
    Class __NSCFString = NSClassFromString(@"__NSCFString");
    
    //replaceCharactersInRange:withString:
    [ZXAvoidCrashRuntime exchangeInstanceMethodWithClass:__NSCFString originalSelector:@selector(replaceCharactersInRange:withString:) swizzledSelector:@selector(zx_replaceCharactersInRange:withString:)];
    
    //insertString:atIndex:
    [ZXAvoidCrashRuntime exchangeInstanceMethodWithClass:__NSCFString originalSelector:@selector(insertString:atIndex:) swizzledSelector:@selector(zx_insertString:atIndex:)];
    
    //deleteCharactersInRange:
    [ZXAvoidCrashRuntime exchangeInstanceMethodWithClass:__NSCFString originalSelector:@selector(deleteCharactersInRange:) swizzledSelector:@selector(zx_deleteCharactersInRange:)];

    //appendString:
    [ZXAvoidCrashRuntime exchangeInstanceMethodWithClass:__NSCFString originalSelector:@selector(appendString:) swizzledSelector:@selector(zx_appendString:)];

    //setString:
    [ZXAvoidCrashRuntime exchangeInstanceMethodWithClass:__NSCFString originalSelector:@selector(setString:) swizzledSelector:@selector(zx_setString:)];

    //replaceOccurrencesOfString:withString:options:range:
    [ZXAvoidCrashRuntime exchangeInstanceMethodWithClass:__NSCFString originalSelector:@selector(replaceOccurrencesOfString:withString:options:range:) swizzledSelector:@selector(zx_replaceOccurrencesOfString:withString:options:range:)];

}


#pragma mark - 原始方法
#pragma mark -replaceCharactersInRange:withString:

//=================================================================
//- (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)aString
//=================================================================

//1.*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString replaceCharactersInRange:withString:]: Range or index out of bounds'
//2.*** nil argument
- (void)zx_replaceCharactersInRange:(NSRange)range withString:(NSString *)aString{
    @try {
        [self zx_replaceCharactersInRange:range withString:aString];
    } @catch (NSException *exception) {
        [ZXAvoidCrashReport crashReportWithException:exception];
    } @finally {
    }
}

#pragma mark - 扩展方法
#pragma mark -insertString:atIndex:

//=====================================================
//- (void)insertString:(NSString *)aString atIndex:(NSUInteger)loc;
//=====================================================

- (void)zx_insertString:(NSString *)aString atIndex:(NSUInteger)loc{
    @try {
        [self zx_insertString:aString atIndex:loc];
    } @catch (NSException *exception) {
        [ZXAvoidCrashReport crashReportWithException:exception];
    } @finally {
    }
}

#pragma mark -deleteCharactersInRange:

//=====================================================
//- (void)deleteCharactersInRange:(NSRange)range;
//=====================================================

- (void)zx_deleteCharactersInRange:(NSRange)range{
    @try {
        [self zx_deleteCharactersInRange:range];
    } @catch (NSException *exception) {
        [ZXAvoidCrashReport crashReportWithException:exception];
    } @finally {
    }
}

#pragma mark -appendString:

//=================================================================
//- (void)appendString:(NSString *)aString
//=====================================================
//*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString appendString:]: nil argument'


- (void)zx_appendString:(NSString *)aString{
    @try {
        [self zx_appendString:aString];
    } @catch (NSException *exception) {
        [ZXAvoidCrashReport crashReportWithException:exception];
    } @finally {
    }
}


#pragma mark -setString:


//=========================================================
//-setString:
//=========================================================
//*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString setString:]: nil argument'
- (void)zx_setString:(NSString *)aString{
    @try {
        [self zx_setString:aString];
    } @catch (NSException *exception) {
        [ZXAvoidCrashReport crashReportWithException:exception];
    } @finally {
    }
}


#pragma mark -replaceOccurrencesOfString:withString:options:range:
//=========================================================
//-replaceOccurrencesOfString:(NSString *)target withString:(NSString *)replacement options:(NSStringCompareOptions)options range:(NSRange)searchRange
//=========================================================
//*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString replaceOccurrencesOfString:withString:options:range:]: nil argument'

- (NSUInteger)zx_replaceOccurrencesOfString:(NSString *)target withString:(NSString *)replacement options:(NSStringCompareOptions)options range:(NSRange)searchRange{
    NSUInteger num;
    @try {
        num = [self zx_replaceOccurrencesOfString:target withString:replacement options:options range:searchRange];
    } @catch (NSException *exception) {
        [ZXAvoidCrashReport crashReportWithException:exception];
    } @finally {
        return num;
    }
}
@end
